#include "listed_timer.h"

using namespace ListedTimer;

SortedTimers::SortedTimers() {
    head = tail = nullptr;
    m_nodes_table = new TimerNode*[6000] {nullptr};
}

SortedTimers::~SortedTimers() {
    TimerNode *t = head;
    while (t != nullptr){
        head = head->next;
        delete t;
        t = head;
    }
}


void SortedTimers::add(int id, int timeout_s, const TimerTask &task) {
    m_lock.lock();
    auto *new_timer = new TimerNode(id, time(nullptr) + timeout_s, task);
    m_nodes_table[id] = new_timer;


    if (head == nullptr) {
        head = tail = new_timer;
    }
    else if (new_timer->expiry_time < head->expiry_time) {
        new_timer->next = head;
//        new_timer->prev = nullptr;
        head->prev = new_timer;
        head = new_timer;
    }
    else {
        insert(new_timer, head);
    }
    m_lock.unlock();
}

void SortedTimers::insert(TimerNode*timer, TimerNode*begin_node) {
    // 按超时值升序插入，时间复杂度O(n)
    TimerNode *prev = begin_node;
    TimerNode *cur = begin_node->next;
    while (cur != nullptr) {
        if (timer->expiry_time < cur->expiry_time) {
            prev->next = timer;
            timer->next = cur;
            cur->prev = timer;
            timer->prev = prev;
            break;
        }
        prev = cur;
        cur = cur->next;
    }

    if (cur == nullptr) {
        prev->next = timer;
        timer->prev = prev;
        timer->next = nullptr;
        tail = timer;
    }
}

void SortedTimers::adjust(int id, uint32_t timeout) {
    // 定时器超时时间延迟时，调整其位置
    m_lock.lock();
    TimerNode *timer = m_nodes_table[id];
    if (timer == nullptr) {
        m_lock.unlock();
        return;
    }

    timer->expiry_time = time(nullptr) + timeout;

    if (timer->next == nullptr ||
        timer->expiry_time < timer->next->expiry_time){
        m_lock.unlock();
        return;
    }


    if (timer == head) {
        head = head->next;
        head->prev = nullptr;
        timer->next = nullptr;
        insert(timer, head);
    }

    else {
        timer->prev->next = timer->next;
        timer->next->prev = timer->prev;
        insert(timer, timer->next);
    }
    m_lock.unlock();
}

void SortedTimers::erase(int id) {

    // 删除节点
    m_lock.lock();
    TimerNode *timer = nullptr;
//    if(m_nodes_table.count(id)) {
//        timer = m_nodes_table[id];
//    }
    timer = m_nodes_table[id];

    if (timer == nullptr){
        m_lock.unlock();
        return;
    }

    timer->id = -1;

//    if (timer == head && timer == tail) {
//        // 只有1个定时器
//        head = nullptr;
//        tail = nullptr;
//    }
//    else if (timer == head) {
//        // 目标定时器为头结点
//        head = head->next;
//        head->prev = nullptr;
//    }
//    else if (timer == tail) {
//        // 目标定时器为尾结点
//        tail = tail->prev;
//        tail->next = nullptr;
//    }
//    else {
//        // 位于链表中间
//        timer->prev->next = timer->next;
//        timer->next->prev = timer->prev;
//    }
//
//    delete timer;
//    m_nodes_table[id] = nullptr;
////    m_nodes_table.erase(id);
    m_lock.unlock();
}

void SortedTimers::tick() {
    // 轮询超时任务
    m_lock.lock();
    if (head == nullptr)  {
        m_lock.unlock();
        return;
    }

    TimerNode *timer = head;
    time_t cur_time = time(nullptr);
    while (timer != nullptr) {
        if (timer->expiry_time > cur_time) {
            // 未到时
            break;
        }

        // 执行任务
        m_lock.unlock();
        if (timer->id != -1) {
            timer->task();
        }
        m_lock.lock();

        // 删除节点
        head = timer->next;
        if (head != nullptr) {
            head->prev = nullptr;
        }

        delete timer;
        timer = head;

    }
    m_lock.unlock();
}

int SortedTimers::get_next_tick() {
    tick();
    long time_slot = -1;
    if (head != nullptr) {
        time_slot = head->expiry_time - time(nullptr);
    }
    return (int)time_slot;
}






